package a.autocode.icop.maker;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.axis.utils.ArrayUtil;
import org.apache.commons.lang3.time.DateUtils;

import jplat.tools.file.XFileTools;
import jplat.tools.string.DateUtil;
import jplat.tools.string.StringUtil;
import jplat.tools.string.XLog;
import a.autocode.JBaseConfigInfo;
import a.autocode.JBaseFieldInfo;
import a.autocode.JBaseServiceMaker;

/**
 * 渠道代码自动生成工具类.
 * 暂时不支持嵌套的列表类，但是支持并行的列表类.
 * @author zhangcq
 * @date Dec 5, 2016
 * @comment
 */
public class ICOPServiceMaker extends JBaseServiceMaker
{
	private static final String PL_XML_ROOT = "__XML_ROOT__";
	private static final String TMP_ROOT_ELEMENT = "@XmlRootElement";
	private static final String CONF_BACKUP_PATH="PORT_FILE_BACKUP_PATH";
	
	//是否有请求体.
	private boolean hasRequest = false;
	
	//是否有响应体.
	private boolean hasResponse = false;
	
	//配置文件读取和文件字符集
	public ICOPServiceMaker( String confpath, String charset )
	{
		super(confpath,charset);
		config = new ICOPConfigInfo();
	}
	
	/****
	 * 新增解析渠道服务包名。
	 */
	protected boolean parseCmd( String name, String value, String newValue )
	{
//		XLog.log(this.getClass().getName());
		ICOPConfigInfo icopConfig = (ICOPConfigInfo)config;
		if ( ICOPConfigInfo.CMD_SERVICE_PACKAGE.equals(name) )
		{
			icopConfig.setServicePackage(newValue);
		}
		else if ( ICOPConfigInfo.CMD_SERVICE_TEMP.equals(name) )
		{
			icopConfig.setServiceTempl(newValue);
		}
		else if ( ICOPConfigInfo.CMD_TRANS_CODE.equals(name) )
		{
//			config.setTransCode(value);
			icopConfig.setBeanName(value);
			icopConfig.setTransCode(value);
		}
		
		return true;
	}
	
	/**
	 * 获取模板值.
	 * 生成文件时,子类可以覆盖该方法指定生成对应的值.
	 * @author zhangcq
	 * @date Dec 12, 2016
	 * @comment 
	 * @return
	 */
	protected Map<String,String> getTempKeyValue( JBaseFieldInfo field, String beanName, String type )
	{
		Map<String,String> valMap = new HashMap<String,String>();
		
		//成员域信息.
		StringBuffer fields = new StringBuffer();
		fields.append("\t//").append(field.getDesc()).append("\n");			//注释.
		fields.append("\t").append(field.javaFormat(beanName, type)).append(";\n\n");	//域信息.
		
		//属性信息.
		StringBuffer props = new StringBuffer();
		props.append(String.format("\t@XmlElement(name=\"%s\")\n",field.getName()));
		props.append(field.javaProtertyString(beanName, type));
		
		valMap.put(PL_BEAN_FIELDS, fields.toString() );		//域信息.
		valMap.put(PL_BEAN_PROPS, props.toString() );		//属性信息.
		
		return valMap;
	}

	@Override
	protected String doTmplReplace(int level, String template, String beanTypeName,
			String type, Map<String, String> priMap)
	{
		// TODO Auto-generated method stub
		if ( level != 0 )		//非顶层类.
		{
			template=template.replace(TMP_ROOT_ELEMENT, "//"+TMP_ROOT_ELEMENT);
		}
		
		if ( JBaseConfigInfo.BEAN_TYPE_REQ.equals(type))
		{
			hasRequest = true;
			template = template.replaceAll(PL_XML_ROOT, "Request");
		}
		else
		{
			hasResponse = true;
			template = template.replaceAll(PL_XML_ROOT, "Response");
		}
		
		return template;
	}

	/**
	 * 生成ICOP的调用服务.
	 * @author zhangcq
	 * @date Dec 6, 2016
	 * @comment 
	 * @return
	 */
	public boolean generateICOPService()
	{
		ICOPConfigInfo icopConfig = (ICOPConfigInfo)config;
		String filepath = icopConfig.getServiceDir()+File.separator+icopConfig.getBeanName()+"ICOPService.java";
		
		//不覆盖，则先检测是否存在.
		if ( !override )
		{
			File myfile = new File(filepath);
			if ( myfile.exists() )
			{
				log(String.format("ERROR:file %s exist at path:%s", myfile.getName(), myfile.getAbsolutePath() ));
				return false;
			}
		}
		
		//初始化模板内容.
		String template = XFileTools.loadFile(icopConfig.getServiceTempl(), "utf-8");
//		log("\n__TMP:"+template+"\n");
		
		//初始化模板.
		icopConfig.confMap.put("GT_TIME", DateUtil.todayStr("yyyy/MM/dd/HH:mm:ss") );
		icopConfig.confMap.put("GT_DATE", DateUtil.todayStr("yyyy-MM-dd") );
		
		//生成接口set方法.
		StringBuffer sbuffer = new StringBuffer();
		List<JBaseFieldInfo> reqList = icopConfig.getReqList();
		for ( int i = 0; i < reqList.size(); ++ i )
		{
			JBaseFieldInfo field = reqList.get(i);
			
			//无法生成list.
			if ( i != 0 )
			{
				sbuffer.append("\t\t");
			}
			sbuffer.append(field.javaCallSetString("icopReqModel", field.getName(), "Req" )).append("\n");
		}
		
		template = template.replace("__SETTERS__", sbuffer.toString());
		
		//context.obtainRspBody
		if ( !hasResponse )		//没有响应体则返回成功失败.
		{
			template=template.replaceAll( "__TRANS_CODE__RspModel1", "boolean" );
			template=template.replaceAll("import1", "//import");
			template=template.replaceAll( "transCtx1", "true; //transCtx" );
		}
		
		//有响应体.
		template=template.replaceAll("__TRANS_CODE__RspModel1", "__TRANS_CODE__RspModel");
		template=template.replaceAll("import1", "import");
		template=template.replaceAll("transCtx1", "transCtx");
		
		//遍历 配置表
		for ( String confKey : icopConfig.confMap.keySet() )
		{
			template = template.replaceAll("__"+confKey+"__",config.confMap.get(confKey));
		}
		
		//遍历域.
		
		
		OutputStream out;
		try {
			out = new FileOutputStream(filepath);
			out.write(template.getBytes("utf-8"));
			out.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		XLog.log("\n----------------------------------------------");
		XLog.log("[SERVICE_PACKAGE]:"+config.getConfValue("SERVICE_PACKAGE"));
		XLog.log("file-generate succeed:"+ new File(filepath).getName());
	
		return true;
	}
	
	public void doPortFileBackup()
	{
		String backupPath = config.getPortBackupPath()+config.getBeanName()+".port";
		if ( StringUtil.isEmpty(backupPath) )
		{
			return;
		}
		
		doPortFileBackup(backupPath);
	}
}
